Octstr *conn_read_line(Connection *conn) { Octstr *result = NULL; long pos; lock_in(conn); /* 10 is the code for linefeed. We don't rely on \n because that * might be a different value on some (strange) systems, and * we are reading from a network connection. */ pos = octstr_search_char(conn->inbuf, 10, conn->inbufpos); if (pos < 0) { unlocked_read(conn); pos = octstr_search_char(conn->inbuf, 10, conn->inbufpos); if (pos < 0) { unlock_in(conn); return NULL; } } result = unlocked_get(conn, pos - conn->inbufpos); gw_claim_area(result); /* Skip the LF, which we left in the buffer */ conn->inbufpos++; /* If the line was terminated with CR LF, we have to remove * the CR from the result. */ if (octstr_len(result) > 0 && octstr_get_char(result, octstr_len(result) - 1) == 13) octstr_delete(result, octstr_len(result) - 1, 1); unlock_in(conn); return result; }
int read_from_bearerbox_real(Connection *conn, Msg **msg, double seconds) { int ret; Octstr *pack; pack = NULL; *msg = NULL; while (program_status != shutting_down) { pack = conn_read_withlen(conn); gw_claim_area(pack); if (pack != NULL) break; if (conn_error(conn)) { error(0, "Error reading from bearerbox, disconnecting."); return -1; } if (conn_eof(conn)) { error(0, "Connection closed by the bearerbox."); return -1; } ret = conn_wait(conn, seconds); if (ret < 0) { error(0, "Connection to bearerbox broke."); return -1; } else if (ret == 1) { /* debug("gwlib.gwlib", 0, "Connection to bearerbox timed out after %.2f seconds.", seconds); */ return 1; } } if (pack == NULL) return -1; *msg = msg_unpack(pack); octstr_destroy(pack); if (*msg == NULL) { error(0, "Failed to unpack data!"); return -1; } return 0; }
Octstr *conn_read_everything(Connection *conn) { Octstr *result = NULL; lock_in(conn); if (unlocked_inbuf_len(conn) == 0) { unlocked_read(conn); if (unlocked_inbuf_len(conn) == 0) { unlock_in(conn); return NULL; } } result = unlocked_get(conn, unlocked_inbuf_len(conn)); gw_claim_area(result); unlock_in(conn); return result; }
static Msg *read_from_box(Boxc *boxconn) { int ret; Octstr *pack; Msg *msg; pack = NULL; while (bb_status != BB_DEAD && boxconn->alive) { /* XXX: if box doesn't send (just keep conn open) we block here while shutdown */ pack = conn_read_withlen(boxconn->conn); gw_claim_area(pack); if (pack != NULL) break; if (conn_error(boxconn->conn)) { info(0, "Read error when reading from box <%s>, disconnecting", octstr_get_cstr(boxconn->client_ip)); return NULL; } if (conn_eof(boxconn->conn)) { info(0, "Connection closed by the box <%s>", octstr_get_cstr(boxconn->client_ip)); return NULL; } ret = conn_wait(boxconn->conn, -1.0); if (ret < 0) { error(0, "Connection to box <%s> broke.", octstr_get_cstr(boxconn->client_ip)); return NULL; } } if (pack == NULL) return NULL; msg = msg_unpack(pack); octstr_destroy(pack); if (msg == NULL) error(0, "Failed to unpack data!"); return msg; }
Octstr *conn_read_fixed(Connection *conn, long length) { Octstr *result = NULL; if (length < 1) return NULL; /* See if the data is already available. If not, try a read(), * then see if we have enough data after that. If not, give up. */ lock_in(conn); if (unlocked_inbuf_len(conn) < length) { unlocked_read(conn); if (unlocked_inbuf_len(conn) < length) { unlock_in(conn); return NULL; } } result = unlocked_get(conn, length); gw_claim_area(result); unlock_in(conn); return result; }
Octstr *conn_read_withlen(Connection *conn) { Octstr *result = NULL; unsigned char lengthbuf[4]; long length = 0; /* for compiler please */ int try, retry; lock_in(conn); for (try = 1; try <= 2; try++) { if (try > 1) unlocked_read(conn); do { retry = 0; /* First get the length. */ if (unlocked_inbuf_len(conn) < 4) continue; octstr_get_many_chars(lengthbuf, conn->inbuf, conn->inbufpos, 4); length = decode_network_long(lengthbuf); if (length < 0) { warning(0, "conn_read_withlen: got negative length, skipping"); conn->inbufpos += 4; retry = 1; } } while(retry == 1); /* Then get the data. */ if (unlocked_inbuf_len(conn) - 4 < length) continue; conn->inbufpos += 4; result = unlocked_get(conn, length); gw_claim_area(result); break; } unlock_in(conn); return result; } Octstr *conn_read_packet(Connection *conn, int startmark, int endmark) { int startpos, endpos; Octstr *result = NULL; int try; lock_in(conn); for (try = 1; try <= 2; try++) { if (try > 1) unlocked_read(conn); /* Find startmark, and discard everything up to it */ if (startmark >= 0) { startpos = octstr_search_char(conn->inbuf, startmark, conn->inbufpos); if (startpos < 0) { conn->inbufpos = octstr_len(conn->inbuf); continue; } else { conn->inbufpos = startpos; } } else { startpos = conn->inbufpos; } /* Find first endmark after startmark */ endpos = octstr_search_char(conn->inbuf, endmark, conn->inbufpos); if (endpos < 0) continue; result = unlocked_get(conn, endpos - startpos + 1); gw_claim_area(result); break; } unlock_in(conn); return result; } #ifdef HAVE_LIBSSL X509 *conn_get_peer_certificate(Connection *conn) { /* Don't know if it needed to be locked , but better safe as crash */ lock_out(conn); lock_in(conn); if (conn->peer_certificate == NULL && conn->ssl != NULL) conn->peer_certificate = SSL_get_peer_certificate(conn->ssl); unlock_in(conn); unlock_out(conn); return conn->peer_certificate; } /* * XXX Alex decalred the RSA callback routine static and now we're getting * warning messages for our automatic compilation tests. So we are commenting * the function out to avoid the warnings. * static RSA *tmp_rsa_callback(SSL *ssl, int export, int key_len) { static RSA *rsa = NULL; debug("gwlib.http", 0, "SSL: Generating new RSA key (export=%d, keylen=%d)", export, key_len); if (export) { rsa = RSA_generate_key(key_len, RSA_F4, NULL, NULL); } else { debug("gwlib.http", 0, "SSL: Export not set"); } return rsa; } */ static Mutex **ssl_static_locks = NULL; /* the call-back function for the openssl crypto thread locking */ static void openssl_locking_function(int mode, int n, const char *file, int line) { if (mode & CRYPTO_LOCK) mutex_lock(ssl_static_locks[n-1]); else mutex_unlock(ssl_static_locks[n-1]); } void openssl_init_locks(void) { int c, maxlocks = CRYPTO_num_locks(); gw_assert(ssl_static_locks == NULL); ssl_static_locks = gw_malloc(sizeof(Mutex *) * maxlocks); for (c = 0; c < maxlocks; c++) ssl_static_locks[c] = mutex_create(); /* after the mutexes have been created, apply the call-back to it */ CRYPTO_set_locking_callback(openssl_locking_function); CRYPTO_set_id_callback((CRYPTO_CALLBACK_PTR)gwthread_self); }