comparison modules/socket.tp @ 370:57d78a0af132

Add code to socket module to allow listening for incoming connections
author Michael Pavone <pavone@retrodev.com>
date Wed, 12 Aug 2015 19:13:31 -0700
parents 4c96a393103e
children
comparison
equal deleted inserted replaced
369:6b5096b07dd5 370:57d78a0af132
39 } andCode: :domain type protocol { 39 } andCode: :domain type protocol {
40 fd <- make_object: (addr_of: obj_int32_meta) NULL 0 40 fd <- make_object: (addr_of: obj_int32_meta) NULL 0
41 fd num!: (socket: (domain num) (type num) (protocol num)) 41 fd num!: (socket: (domain num) (type num) (protocol num))
42 fd 42 fd
43 } 43 }
44 44
45 new <- :domain type protocol { 45 _sock_obj <- :sfd {
46 sfd <- socket: domain type protocol
47 #{ 46 #{
48 fd <- {sfd} 47 fd <- {sfd}
49 48
50 llMessage: close withVars: { 49 llMessage: close withVars: {
51 sfd <- obj_int32 ptr 50 sfd <- obj_int32 ptr
110 } 109 }
111 } 110 }
112 received 111 received
113 } 112 }
114 } 113 }
114 }
115
116 _accept_sock <- :domain type protocol {
117 sfd <- socket: domain type protocol
118 #{
119 fd <- {sfd}
120
121 llMessage: close withVars: {
122 sfd <- obj_int32 ptr
123 } andCode: {
124 sfd <- mcall: fd 1 self
125 close: (sfd num)
126 self
127 }
128
129 llMessage: accept withVars: {
130 sfd <- obj_int32 ptr
131 newfd <- obj_int32 ptr
132 } andCode: {
133 sfd <- mcall: fd 1 self
134 newfd <- make_object: (addr_of: obj_int32_meta) NULL 0
135 //TODO: expose peer address
136 newfd num!: (accept: (sfd num) NULL NULL)
137 if: (newfd num) >= 0 {
138 mcall: value 2 option (mcall: _sock_obj 2 socket newfd)
139 } else: {
140 mcall: none 1 option
141 }
142 }
143 }
144 }
145
146 new <- :domain type protocol {
147 sfd <- socket: domain type protocol
148 _sock_obj: sfd
115 } 149 }
116 150
117 llMessage: _connectTo:onPort withVars: { 151 llMessage: _connectTo:onPort withVars: {
118 host <- string ptr 152 host <- string ptr
119 port <- string ptr 153 port <- string ptr
143 connect: (sfd num) (info ai_addr) (info ai_addrlen) 177 connect: (sfd num) (info ai_addr) (info ai_addrlen)
144 178
145 freeaddrinfo: info 179 freeaddrinfo: info
146 sock 180 sock
147 } 181 }
182
148 183
149 connectTo:onPort <- :host :port { 184 connectTo:onPort <- :host :port {
150 _connectTo: host onPort: (string: port) 185 _connectTo: host onPort: (string: port)
151 } 186 }
152 listenOn <- :port { 187 llMessage: listenAt:onPort withVars: {
153 } 188 ohost <- object ptr
154 listenAt:onPort <- :host :port { 189 host <- string ptr
190 oport <- object ptr
191 port <- string ptr
192 hints <- struct: addrinfo
193 info <- (struct: addrinfo) ptr
194 curinfo <- (struct: addrinfo) ptr
195 domain <- obj_int32 ptr
196 type <- obj_int32 ptr
197 protocol <- obj_int32 ptr
198 sock <- object ptr
199 sfd <- obj_int32 ptr
200 result <- int32_t
201 hstr <- uint8_t ptr
202 } andCode: :ohost :oport {
203 host <- (mcall: string 1 ohost) castTo: (string ptr)
204 port <- (mcall: string 1 oport) castTo: (string ptr)
205 memset: (addr_of: hints) 0 (sizeof: hints)
206 hints ai_family!: AF_UNSPEC
207 hints ai_socktype!: SOCK_STREAM
208 hints ai_flags!: AI_PASSIVE
209 hints ai_protocol!: 0
210 hints ai_canonname!: NULL
211 hints ai_addr!: NULL
212 hints ai_next!: NULL
213 result <- getaddrinfo
214 if: (host bytes) = 0 {
215 hstr <- NULL
216 } else: {
217 hstr <- host data
218 }
219 result <- getaddrinfo: hstr (port data) (addr_of: hints) (addr_of: info)
220 if: result = 0 {
221 curinfo <- info
222 domain <- make_object: (addr_of: obj_int32_meta) NULL 0
223 type <- make_object: (addr_of: obj_int32_meta) NULL 0
224 protocol <- make_object: (addr_of: obj_int32_meta) NULL 0
225 while: { curinfo != NULL } do: {
226 domain num!: (curinfo ai_family)
227 type num!: (curinfo ai_socktype)
228 protocol num!: (curinfo ai_protocol)
229 sock <- mcall: _accept_sock 4 self domain type protocol
230 sfd <- (mcall: fd 1 sock) castTo: (obj_int32 ptr)
231 if: (sfd num) != -1 {
232 result <- bind: (sfd num) (curinfo ai_addr) (curinfo ai_addrlen)
233 if: result = 0 {
234 curinfo <- NULL
235 } else: {
236 //failed to bind, close this socket so we can try again
237 close: (sfd num)
238 sock <- NULL
239 }
240 }
241 }
242 if: sock {
243 listen: (sfd num) 8
244 mcall: value 2 option sock
245 } else: {
246 mcall: none 1 option
247 }
248 } else: {
249 mcall: none 1 option
250 }
251 }
252
253 listenOnPort <- :port {
254 listenAt: "" onPort: port
155 } 255 }
156 } 256 }