int sim_slirp_send (SLIRP *slirp, const char *msg, size_t len, int flags) { struct slirp_write_request *request; int wake_needed = 0; /* Get a buffer */ pthread_mutex_lock (&slirp->write_buffer_lock); if (NULL != (request = slirp->write_buffers)) slirp->write_buffers = request->next; pthread_mutex_unlock (&slirp->write_buffer_lock); if (NULL == request) request = (struct slirp_write_request *)g_malloc(sizeof(*request)); /* Copy buffer contents */ request->len = len; memcpy(request->msg, msg, len); /* Insert buffer at the end of the write list (to make sure that */ /* packets make it to the wire in the order they were presented here) */ pthread_mutex_lock (&slirp->write_buffer_lock); request->next = NULL; if (slirp->write_requests) { struct slirp_write_request *last_request = slirp->write_requests; while (last_request->next) { last_request = last_request->next; } last_request->next = request; } else { slirp->write_requests = request; wake_needed = 1; } pthread_mutex_unlock (&slirp->write_buffer_lock); if (wake_needed) sim_write_sock (slirp->db_chime, msg, 0); return len; }
/* cannot use sim_check_conn to check whether read will return an error */ static t_stat net_svc(UNIT *uptr) { int32 i, j, k, r; SOCKET s; static char svcBuffer[BUFFER_LENGTH]; if (net_unit.flags & UNIT_ATT) { /* cannot remove due to following else */ sim_activate(&net_unit, net_unit.wait); /* continue poll */ if (net_unit.flags & UNIT_SERVER) { for (i = 1; i <= MAX_CONNECTIONS; i++) if (serviceDescriptor[i].ioSocket == 0) { s = sim_accept_conn(serviceDescriptor[1].masterSocket, NULL); if (s != INVALID_SOCKET) { serviceDescriptor[i].ioSocket = s; sim_debug(ACCEPT_MSG, &net_dev, "NET: " ADDRESS_FORMAT " Accepted connection %i with socket %i.\n", PCX, i, s); } } } else if (serviceDescriptor[0].ioSocket == 0) { serviceDescriptor[0].ioSocket = sim_connect_sock(net_unit.filename, "localhost", "3000"); if (serviceDescriptor[0].ioSocket == INVALID_SOCKET) return SCPE_IOERR; printf("\rWaiting for server ... Type g<return> (possibly twice) when ready" NLP); return SCPE_STOP; } for (i = 0; i <= MAX_CONNECTIONS; i++) if (serviceDescriptor[i].ioSocket) { if (serviceDescriptor[i].inputSize < BUFFER_LENGTH) { /* there is space left in inputBuffer */ r = sim_read_sock(serviceDescriptor[i].ioSocket, svcBuffer, BUFFER_LENGTH - serviceDescriptor[i].inputSize); if (r == -1) { sim_debug(DROP_MSG, &net_dev, "NET: " ADDRESS_FORMAT " Drop connection %i with socket %i.\n", PCX, i, serviceDescriptor[i].ioSocket); sim_close_sock(serviceDescriptor[i].ioSocket, FALSE); serviceDescriptor[i].ioSocket = 0; serviceDescriptor_reset(i); continue; } else { for (j = 0; j < r; j++) { serviceDescriptor[i].inputBuffer[serviceDescriptor[i].inputPosWrite++] = svcBuffer[j]; if (serviceDescriptor[i].inputPosWrite == BUFFER_LENGTH) serviceDescriptor[i].inputPosWrite = 0; } serviceDescriptor[i].inputSize += r; } } if (serviceDescriptor[i].outputSize > 0) { /* there is something to write in outputBuffer */ k = serviceDescriptor[i].outputPosRead; for (j = 0; j < serviceDescriptor[i].outputSize; j++) { svcBuffer[j] = serviceDescriptor[i].outputBuffer[k++]; if (k == BUFFER_LENGTH) k = 0; } r = sim_write_sock(serviceDescriptor[i].ioSocket, svcBuffer, serviceDescriptor[i].outputSize); if (r >= 0) { serviceDescriptor[i].outputSize -= r; serviceDescriptor[i].outputPosRead += r; if (serviceDescriptor[i].outputPosRead >= BUFFER_LENGTH) serviceDescriptor[i].outputPosRead -= BUFFER_LENGTH; } else printf("write %i" NLP, r); } } } return SCPE_OK; }