Changes in uspace/srv/net/tl/tcp/ucall.c [ae481e0:74c99b5] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/tcp/ucall.c
rae481e0 r74c99b5 53 53 * @param fsock Foreign socket 54 54 * @param acpass Active/passive 55 * @param oflags Open flags56 55 * @param conn Connection 57 56 * … … 66 65 */ 67 66 tcp_error_t tcp_uc_open(tcp_sock_t *lsock, tcp_sock_t *fsock, acpass_t acpass, 68 tcp_ open_flags_t oflags, tcp_conn_t **conn)67 tcp_conn_t **conn) 69 68 { 70 69 tcp_conn_t *nconn; 71 70 72 log_msg(LVL_DEBUG, "tcp_uc_open(%p, %p, %s, % s, %p)",71 log_msg(LVL_DEBUG, "tcp_uc_open(%p, %p, %s, %p)", 73 72 lsock, fsock, acpass == ap_active ? "active" : "passive", 74 oflags == tcp_open_nonblock ? "nonblock" : "none",conn);73 conn); 75 74 76 75 nconn = tcp_conn_new(lsock, fsock); … … 82 81 } 83 82 84 if (oflags == tcp_open_nonblock) {85 *conn = nconn;86 return TCP_EOK;87 }88 89 83 /* Wait for connection to be established or reset */ 90 84 log_msg(LVL_DEBUG, "tcp_uc_open: Wait for connection."); 91 fibril_mutex_lock(&nconn-> lock);85 fibril_mutex_lock(&nconn->cstate_lock); 92 86 while (nconn->cstate == st_listen || 93 87 nconn->cstate == st_syn_sent || 94 88 nconn->cstate == st_syn_received) { 95 fibril_condvar_wait(&nconn->cstate_cv, &nconn-> lock);89 fibril_condvar_wait(&nconn->cstate_cv, &nconn->cstate_lock); 96 90 } 97 91 … … 99 93 log_msg(LVL_DEBUG, "tcp_uc_open: Connection was reset."); 100 94 assert(nconn->cstate == st_closed); 101 fibril_mutex_unlock(&nconn-> lock);95 fibril_mutex_unlock(&nconn->cstate_lock); 102 96 return TCP_ERESET; 103 97 } 104 98 105 fibril_mutex_unlock(&nconn-> lock);99 fibril_mutex_unlock(&nconn->cstate_lock); 106 100 log_msg(LVL_DEBUG, "tcp_uc_open: Connection was established."); 107 101 108 102 *conn = nconn; 109 log_msg(LVL_DEBUG, "tcp_uc_open -> %p", nconn);110 103 return TCP_EOK; 111 104 } … … 120 113 log_msg(LVL_DEBUG, "%s: tcp_uc_send()", conn->name); 121 114 122 fibril_mutex_lock(&conn->lock); 123 124 if (conn->cstate == st_closed) { 125 fibril_mutex_unlock(&conn->lock); 115 if (conn->cstate == st_closed) 126 116 return TCP_ENOTEXIST; 127 }128 117 129 118 if (conn->cstate == st_listen) { … … 132 121 } 133 122 134 135 if (conn->snd_buf_fin) { 136 fibril_mutex_unlock(&conn->lock); 123 if (conn->snd_buf_fin) 137 124 return TCP_ECLOSING; 138 }139 125 140 126 while (size > 0) { 141 127 buf_free = conn->snd_buf_size - conn->snd_buf_used; 142 while (buf_free == 0 && !conn->reset) { 143 log_msg(LVL_DEBUG, "%s: buf_free == 0, waiting.", 144 conn->name); 145 fibril_condvar_wait(&conn->snd_buf_cv, &conn->lock); 146 buf_free = conn->snd_buf_size - conn->snd_buf_used; 147 } 148 149 if (conn->reset) { 150 fibril_mutex_unlock(&conn->lock); 128 while (buf_free == 0 && !conn->reset) 129 tcp_tqueue_new_data(conn); 130 131 if (conn->reset) 151 132 return TCP_ERESET; 152 }153 133 154 134 xfer_size = min(size, buf_free); … … 159 139 conn->snd_buf_used += xfer_size; 160 140 size -= xfer_size; 161 162 tcp_tqueue_new_data(conn);163 141 } 164 142 165 143 tcp_tqueue_new_data(conn); 166 fibril_mutex_unlock(&conn->lock);167 144 168 145 return TCP_EOK; … … 177 154 log_msg(LVL_DEBUG, "%s: tcp_uc_receive()", conn->name); 178 155 179 fibril_mutex_lock(&conn->lock); 180 181 if (conn->cstate == st_closed) { 182 fibril_mutex_unlock(&conn->lock); 156 if (conn->cstate == st_closed) 183 157 return TCP_ENOTEXIST; 184 } 158 159 fibril_mutex_lock(&conn->rcv_buf_lock); 185 160 186 161 /* Wait for data to become available */ 187 162 while (conn->rcv_buf_used == 0 && !conn->rcv_buf_fin && !conn->reset) { 188 163 log_msg(LVL_DEBUG, "tcp_uc_receive() - wait for data"); 189 fibril_condvar_wait(&conn->rcv_buf_cv, &conn-> lock);164 fibril_condvar_wait(&conn->rcv_buf_cv, &conn->rcv_buf_lock); 190 165 } 191 166 192 167 if (conn->rcv_buf_used == 0) { 168 fibril_mutex_unlock(&conn->rcv_buf_lock); 169 193 170 *rcvd = 0; 194 171 *xflags = 0; … … 196 173 if (conn->rcv_buf_fin) { 197 174 /* End of data, peer closed connection */ 198 fibril_mutex_unlock(&conn->lock);199 175 return TCP_ECLOSING; 200 176 } else { 201 177 /* Connection was reset */ 202 178 assert(conn->reset); 203 fibril_mutex_unlock(&conn->lock);204 179 return TCP_ERESET; 205 180 } … … 217 192 conn->rcv_wnd += xfer_size; 218 193 194 fibril_mutex_unlock(&conn->rcv_buf_lock); 195 219 196 /* TODO */ 220 197 *xflags = 0; … … 226 203 conn->name, xfer_size); 227 204 228 fibril_mutex_unlock(&conn->lock);229 230 205 return TCP_EOK; 231 206 } … … 236 211 log_msg(LVL_DEBUG, "%s: tcp_uc_close()", conn->name); 237 212 238 fibril_mutex_lock(&conn->lock); 239 240 if (conn->cstate == st_closed) { 241 fibril_mutex_unlock(&conn->lock); 213 if (conn->cstate == st_closed) 242 214 return TCP_ENOTEXIST; 243 } 244 245 if (conn->snd_buf_fin) { 246 fibril_mutex_unlock(&conn->lock); 215 216 if (conn->snd_buf_fin) 247 217 return TCP_ECLOSING; 248 }249 218 250 219 conn->snd_buf_fin = true; 251 220 tcp_tqueue_new_data(conn); 252 221 253 fibril_mutex_unlock(&conn->lock);254 222 return TCP_EOK; 255 223 } … … 265 233 { 266 234 log_msg(LVL_DEBUG, "tcp_uc_status()"); 267 cstatus->cstate = conn->cstate; 268 } 269 270 /** Delete connection user call. 271 * 272 * (Not in spec.) Inform TCP that the user is done with this connection 273 * and will not make any further calls/references to it. TCP can deallocate 274 * the connection from now on. 275 */ 276 void tcp_uc_delete(tcp_conn_t *conn) 277 { 278 log_msg(LVL_DEBUG, "tcp_uc_delete()"); 279 tcp_conn_delete(conn); 280 } 281 282 void tcp_uc_set_cstate_cb(tcp_conn_t *conn, tcp_cstate_cb_t cb, void *arg) 283 { 284 log_msg(LVL_DEBUG, "tcp_uc_set_ctate_cb(%p, %p, %p)", 285 conn, cb, arg); 286 287 conn->cstate_cb = cb; 288 conn->cstate_cb_arg = arg; 289 } 235 } 236 290 237 291 238 /* … … 302 249 sp->local.addr.ipv4, sp->local.port); 303 250 304 conn = tcp_conn_find_ref(sp); 305 if (conn == NULL) { 306 log_msg(LVL_WARN, "No connection found."); 251 conn = tcp_conn_find(sp); 252 if (conn != NULL && conn->cstate != st_closed) { 253 if (conn->ident.foreign.addr.ipv4 == TCP_IPV4_ANY) 254 conn->ident.foreign.addr.ipv4 = sp->foreign.addr.ipv4; 255 if (conn->ident.foreign.port == TCP_PORT_ANY) 256 conn->ident.foreign.port = sp->foreign.port; 257 if (conn->ident.local.addr.ipv4 == TCP_IPV4_ANY) 258 conn->ident.local.addr.ipv4 = sp->local.addr.ipv4; 259 260 tcp_conn_segment_arrived(conn, seg); 261 } else { 262 if (conn == NULL) 263 log_msg(LVL_WARN, "No connection found."); 264 else 265 log_msg(LVL_WARN, "Connection is closed."); 307 266 tcp_unexpected_segment(sp, seg); 308 return; 309 } 310 311 fibril_mutex_lock(&conn->lock); 312 313 if (conn->cstate == st_closed) { 314 log_msg(LVL_WARN, "Connection is closed."); 315 tcp_unexpected_segment(sp, seg); 316 fibril_mutex_unlock(&conn->lock); 317 tcp_conn_delref(conn); 318 return; 319 } 320 321 if (conn->ident.foreign.addr.ipv4 == TCP_IPV4_ANY) 322 conn->ident.foreign.addr.ipv4 = sp->foreign.addr.ipv4; 323 if (conn->ident.foreign.port == TCP_PORT_ANY) 324 conn->ident.foreign.port = sp->foreign.port; 325 if (conn->ident.local.addr.ipv4 == TCP_IPV4_ANY) 326 conn->ident.local.addr.ipv4 = sp->local.addr.ipv4; 327 328 tcp_conn_segment_arrived(conn, seg); 329 330 fibril_mutex_unlock(&conn->lock); 331 tcp_conn_delref(conn); 267 } 332 268 } 333 269
Note:
See TracChangeset
for help on using the changeset viewer.