clientConn.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. package goStrongswanVici
  2. import (
  3. "fmt"
  4. "io"
  5. "net"
  6. "time"
  7. )
  8. const (
  9. DefaultReadTimeout = 15 * time.Second
  10. )
  11. // This object is not thread safe.
  12. // if you want concurrent, you need create more clients.
  13. type ClientConn struct {
  14. conn net.Conn
  15. responseChan chan segment
  16. eventHandlers map[string]func(response map[string]interface{})
  17. lastError error
  18. // ReadTimeout specifies a time limit for requests made
  19. // by this client.
  20. ReadTimeout time.Duration
  21. }
  22. func (c *ClientConn) Close() error {
  23. close(c.responseChan)
  24. c.lastError = io.ErrClosedPipe
  25. return c.conn.Close()
  26. }
  27. func NewClientConn(conn net.Conn) (client *ClientConn) {
  28. client = &ClientConn{
  29. conn: conn,
  30. responseChan: make(chan segment, 2),
  31. eventHandlers: map[string]func(response map[string]interface{}){},
  32. ReadTimeout: DefaultReadTimeout,
  33. }
  34. go client.readThread()
  35. return client
  36. }
  37. // it dial from unix:///var/run/charon.vici
  38. func NewClientConnFromDefaultSocket() (client *ClientConn, err error) {
  39. conn, err := net.Dial("unix", "/var/run/charon.vici")
  40. if err != nil {
  41. return
  42. }
  43. return NewClientConn(conn), nil
  44. }
  45. func (c *ClientConn) Request(apiname string, request map[string]interface{}) (response map[string]interface{}, err error) {
  46. err = writeSegment(c.conn, segment{
  47. typ: stCMD_REQUEST,
  48. name: apiname,
  49. msg: request,
  50. })
  51. if err != nil {
  52. fmt.Printf("error writing segment \n")
  53. return
  54. }
  55. outMsg := c.readResponse()
  56. if c.lastError != nil {
  57. return nil, c.lastError
  58. }
  59. if outMsg.typ != stCMD_RESPONSE {
  60. return nil, fmt.Errorf("[%s] response error %d", apiname, outMsg.typ)
  61. }
  62. return outMsg.msg, nil
  63. }
  64. func (c *ClientConn) readResponse() segment {
  65. select {
  66. case outMsg := <-c.responseChan:
  67. return outMsg
  68. case <-time.After(c.ReadTimeout):
  69. if c.lastError == nil {
  70. c.lastError = fmt.Errorf("Timeout waiting for message response")
  71. }
  72. return segment{}
  73. }
  74. }
  75. func (c *ClientConn) RegisterEvent(name string, handler func(response map[string]interface{})) (err error) {
  76. if c.eventHandlers[name] != nil {
  77. return fmt.Errorf("[event %s] register a event twice.", name)
  78. }
  79. c.eventHandlers[name] = handler
  80. err = writeSegment(c.conn, segment{
  81. typ: stEVENT_REGISTER,
  82. name: name,
  83. })
  84. if err != nil {
  85. delete(c.eventHandlers, name)
  86. return
  87. }
  88. outMsg := c.readResponse()
  89. //fmt.Printf("registerEvent %#v\n", outMsg)
  90. if c.lastError != nil {
  91. delete(c.eventHandlers, name)
  92. return c.lastError
  93. }
  94. if outMsg.typ != stEVENT_CONFIRM {
  95. delete(c.eventHandlers, name)
  96. return fmt.Errorf("[event %s] response error %d", name, outMsg.typ)
  97. }
  98. return nil
  99. }
  100. func (c *ClientConn) UnregisterEvent(name string) (err error) {
  101. err = writeSegment(c.conn, segment{
  102. typ: stEVENT_UNREGISTER,
  103. name: name,
  104. })
  105. if err != nil {
  106. return
  107. }
  108. outMsg := c.readResponse()
  109. //fmt.Printf("UnregisterEvent %#v\n", outMsg)
  110. if c.lastError != nil {
  111. return c.lastError
  112. }
  113. if outMsg.typ != stEVENT_CONFIRM {
  114. return fmt.Errorf("[event %s] response error %d", name, outMsg.typ)
  115. }
  116. delete(c.eventHandlers, name)
  117. return nil
  118. }
  119. func (c *ClientConn) readThread() {
  120. for {
  121. outMsg, err := readSegment(c.conn)
  122. if err != nil {
  123. c.lastError = err
  124. return
  125. }
  126. switch outMsg.typ {
  127. case stCMD_RESPONSE, stEVENT_CONFIRM:
  128. c.responseChan <- outMsg
  129. case stEVENT:
  130. handler := c.eventHandlers[outMsg.name]
  131. if handler != nil {
  132. handler(outMsg.msg)
  133. }
  134. default:
  135. c.lastError = fmt.Errorf("[Client.readThread] unknow msg type %d", outMsg.typ)
  136. return
  137. }
  138. }
  139. }