123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- package goStrongswanVici
- import (
- "fmt"
- "io"
- "net"
- "time"
- )
- const (
- DefaultReadTimeout = 15 * time.Second
- )
- // This object is not thread safe.
- // if you want concurrent, you need create more clients.
- type ClientConn struct {
- conn net.Conn
- responseChan chan segment
- eventHandlers map[string]func(response map[string]interface{})
- lastError error
- // ReadTimeout specifies a time limit for requests made
- // by this client.
- ReadTimeout time.Duration
- }
- func (c *ClientConn) Close() error {
- close(c.responseChan)
- c.lastError = io.ErrClosedPipe
- return c.conn.Close()
- }
- func NewClientConn(conn net.Conn) (client *ClientConn) {
- client = &ClientConn{
- conn: conn,
- responseChan: make(chan segment, 2),
- eventHandlers: map[string]func(response map[string]interface{}){},
- ReadTimeout: DefaultReadTimeout,
- }
- go client.readThread()
- return client
- }
- // it dial from unix:///var/run/charon.vici
- func NewClientConnFromDefaultSocket() (client *ClientConn, err error) {
- conn, err := net.Dial("unix", "/var/run/charon.vici")
- if err != nil {
- return
- }
- return NewClientConn(conn), nil
- }
- func (c *ClientConn) Request(apiname string, request map[string]interface{}) (response map[string]interface{}, err error) {
- err = writeSegment(c.conn, segment{
- typ: stCMD_REQUEST,
- name: apiname,
- msg: request,
- })
- if err != nil {
- fmt.Printf("error writing segment \n")
- return
- }
- outMsg := c.readResponse()
- if c.lastError != nil {
- return nil, c.lastError
- }
- if outMsg.typ != stCMD_RESPONSE {
- return nil, fmt.Errorf("[%s] response error %d", apiname, outMsg.typ)
- }
- return outMsg.msg, nil
- }
- func (c *ClientConn) readResponse() segment {
- select {
- case outMsg := <-c.responseChan:
- return outMsg
- case <-time.After(c.ReadTimeout):
- if c.lastError == nil {
- c.lastError = fmt.Errorf("Timeout waiting for message response")
- }
- return segment{}
- }
- }
- func (c *ClientConn) RegisterEvent(name string, handler func(response map[string]interface{})) (err error) {
- if c.eventHandlers[name] != nil {
- return fmt.Errorf("[event %s] register a event twice.", name)
- }
- c.eventHandlers[name] = handler
- err = writeSegment(c.conn, segment{
- typ: stEVENT_REGISTER,
- name: name,
- })
- if err != nil {
- delete(c.eventHandlers, name)
- return
- }
- outMsg := c.readResponse()
- //fmt.Printf("registerEvent %#v\n", outMsg)
- if c.lastError != nil {
- delete(c.eventHandlers, name)
- return c.lastError
- }
- if outMsg.typ != stEVENT_CONFIRM {
- delete(c.eventHandlers, name)
- return fmt.Errorf("[event %s] response error %d", name, outMsg.typ)
- }
- return nil
- }
- func (c *ClientConn) UnregisterEvent(name string) (err error) {
- err = writeSegment(c.conn, segment{
- typ: stEVENT_UNREGISTER,
- name: name,
- })
- if err != nil {
- return
- }
- outMsg := c.readResponse()
- //fmt.Printf("UnregisterEvent %#v\n", outMsg)
- if c.lastError != nil {
- return c.lastError
- }
- if outMsg.typ != stEVENT_CONFIRM {
- return fmt.Errorf("[event %s] response error %d", name, outMsg.typ)
- }
- delete(c.eventHandlers, name)
- return nil
- }
- func (c *ClientConn) readThread() {
- for {
- outMsg, err := readSegment(c.conn)
- if err != nil {
- c.lastError = err
- return
- }
- switch outMsg.typ {
- case stCMD_RESPONSE, stEVENT_CONFIRM:
- c.responseChan <- outMsg
- case stEVENT:
- handler := c.eventHandlers[outMsg.name]
- if handler != nil {
- handler(outMsg.msg)
- }
- default:
- c.lastError = fmt.Errorf("[Client.readThread] unknow msg type %d", outMsg.typ)
- return
- }
- }
- }
|