/*** 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; }
/*** Non-blocking write *******************************************************/ int pptp_write_some(PPTP_CONN * conn) { ssize_t retval; assert(conn && conn->call); retval = write(conn->inet_sock, conn->write_buffer, conn->write_size); if (retval < 0) { /* error. */ if (errno == EAGAIN || errno == EINTR) { return 0; } else { /* a real error */ log("write error: %s", strerror(errno)); return -1; } } assert(retval <= conn->write_size); conn->write_size -= retval; memmove(conn->write_buffer, conn->write_buffer + retval, conn->write_size); ctrlp_rep(conn->write_buffer, retval, 0); return 0; }