/*** handle any pptp file descriptors set in fd_set, and clear them ***********/ int pptp_dispatch(PPTP_CONN * conn, fd_set * read_set, fd_set * write_set) { int r = 0; assert(conn && conn->call); /* Check for signals */ if (FD_ISSET(sigpipe_fd(), read_set)) { if (sigpipe_read() == SIGALRM) pptp_handle_timer(); FD_CLR(sigpipe_fd(), read_set); } /* Check write_set could be set. */ if (FD_ISSET(conn->inet_sock, write_set)) { FD_CLR(conn->inet_sock, write_set); if (conn->write_size > 0) r = pptp_write_some(conn);/* write as much as we can without blocking */ } /* Check read_set */ if (r >= 0 && FD_ISSET(conn->inet_sock, read_set)) { void *buffer; size_t size; FD_CLR(conn->inet_sock, read_set); r = pptp_read_some(conn); /* read as much as we can without blocking */ if (r < 0) return r; /* make packets of the buffer, while we can. */ while (r >= 0 && pptp_make_packet(conn, &buffer, &size)) { r = pptp_dispatch_packet(conn, buffer, size); free(buffer); } } /* That's all, folks. Simple, eh? */ return r; }
/*** pptp_send_ctrl_packet ****************************************************/ int pptp_send_ctrl_packet(PPTP_CONN * conn, void * buffer, size_t size) { assert(conn && conn->call); assert(buffer); if( conn->write_size > 0) pptp_write_some( conn); if( conn->write_size == 0) { ssize_t retval; retval = write(conn->inet_sock, buffer, size); if (retval < 0) { /* error. */ if (errno == EAGAIN || errno == EINTR) { /* ignore */; retval = 0; } else { /* a real error */ log("write error: %s", strerror(errno)); pptp_conn_destroy(conn); /* shut down fast. */ return 0; } } ctrlp_rep( buffer, retval, 0); size -= retval; if( size <= 0) return 1; } /* Shove anything not written into the write buffer */ if (conn->write_size + size > conn->write_alloc) { /* need more memory */ char *new_buffer = realloc(conn->write_buffer, sizeof(*(conn->write_buffer)) * conn->write_alloc * 2); if (new_buffer == NULL) { log("Out of memory"); return 0; } conn->write_alloc *= 2; conn->write_buffer = new_buffer; } memcpy(conn->write_buffer + conn->write_size, buffer, size); conn->write_size += size; ctrlp_rep( buffer,size,1); return 1; }