use of com.biglybt.core.util.AESemaphore in project BiglyBT by BiglySoftware.
the class NetworkAdminHTTPProxyImpl method getDetails.
@Override
public Details getDetails() throws NetworkAdminException {
final int RES_CONNECT_FAILED = 0;
final int RES_PROXY_FAILED = 1;
final int RES_OK = 3;
final AESemaphore sem = new AESemaphore("NetworkAdminSocksProxy:test");
final int[] result = { RES_CONNECT_FAILED };
final NetworkAdminException[] error = { null };
final ProxyDetails[] details = { null };
try {
InetSocketAddress socks_address = new InetSocketAddress(InetAddress.getByName(http_host), Integer.parseInt(http_port));
final InetSocketAddress target_address = new InetSocketAddress(TARGET_HOST, TARGET_PORT);
TCPConnectionManager.ConnectListener connect_listener = new TCPConnectionManager.ConnectListener() {
@Override
public int connectAttemptStarted(int default_connect_timeout) {
return (default_connect_timeout);
}
@Override
public void connectSuccess(SocketChannel channel) {
final TCPTransportImpl transport = new TCPTransportImpl((ProtocolEndpointTCP) ProtocolEndpointFactory.createEndpoint(ProtocolEndpoint.PROTOCOL_TCP, target_address), false, false, null);
transport.setFilter(TCPTransportHelperFilterFactory.createTransparentFilter(channel));
final long start_time = SystemTime.getCurrentTime();
try {
String get_str = VersionCheckClient.getSingleton().getHTTPGetString(true, false);
ByteBuffer request = ByteBuffer.wrap(get_str.getBytes());
while (request.hasRemaining()) {
if (transport.write(new ByteBuffer[] { request }, 0, 1) < 1) {
if (SystemTime.getCurrentTime() - start_time > 30 * 1000) {
String error = "proxy handshake message send timed out after 30sec";
Debug.out(error);
throw new IOException(error);
}
try {
Thread.sleep(50);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
TCPNetworkManager.getSingleton().getReadSelector().register(transport.getSocketChannel(), new VirtualChannelSelector.VirtualSelectorListener() {
private final byte[] reply_buffer = new byte[8192];
private final ByteBuffer reply = ByteBuffer.wrap(reply_buffer);
@Override
public boolean selectSuccess(VirtualChannelSelector selector, SocketChannel sc, Object attachment) {
try {
if (SystemTime.getCurrentTime() - start_time > 30 * 1000) {
throw (new Exception("Timeout"));
}
long len = transport.read(new ByteBuffer[] { reply }, 0, 1);
if (len <= 0) {
return (false);
}
String str = new String(reply_buffer, 0, reply.position());
if (str.contains(NL + NL)) {
System.out.println(str);
String server_name = "unknown";
String auth = "none";
String response = "unknown";
StringTokenizer tok = new StringTokenizer(str, "\n");
int line_num = 0;
while (tok.hasMoreTokens()) {
String token = tok.nextToken().trim();
if (token.length() == 0) {
continue;
}
line_num++;
if (line_num == 1) {
int pos = token.indexOf(' ');
if (pos != -1) {
response = token.substring(pos + 1).trim();
}
} else {
int pos = token.indexOf(':');
if (pos != -1) {
String lhs = token.substring(0, pos).trim().toLowerCase(MessageText.LOCALE_ENGLISH);
String rhs = token.substring(pos + 1).trim();
if (lhs.equals("server")) {
if (!response.startsWith("200")) {
server_name = rhs;
}
} else if (lhs.equals("via")) {
server_name = rhs;
int p = server_name.indexOf(' ');
if (p != -1) {
server_name = server_name.substring(p + 1).trim();
}
} else if (lhs.equals("proxy-authenticate")) {
auth = rhs;
}
}
}
}
details[0] = new ProxyDetails(server_name, response, auth);
transport.close("Done");
result[0] = RES_OK;
sem.release();
} else {
TCPNetworkManager.getSingleton().getReadSelector().resumeSelects(transport.getSocketChannel());
}
return (true);
} catch (Throwable t) {
return false;
}
}
@Override
public void selectFailure(VirtualChannelSelector selector, SocketChannel sc, Object attachment, Throwable msg) {
result[0] = RES_PROXY_FAILED;
error[0] = new NetworkAdminException("Proxy error", msg);
transport.close("Proxy error");
sem.release();
}
}, null);
} catch (Throwable t) {
result[0] = RES_PROXY_FAILED;
error[0] = new NetworkAdminException("Proxy connect failed", t);
sem.release();
}
}
@Override
public void connectFailure(Throwable failure_msg) {
result[0] = RES_CONNECT_FAILED;
error[0] = new NetworkAdminException("Connect failed", failure_msg);
sem.release();
}
};
TCPNetworkManager.getSingleton().getConnectDisconnectManager().requestNewConnection(socks_address, connect_listener, ProtocolEndpoint.CONNECT_PRIORITY_MEDIUM);
} catch (Throwable e) {
result[0] = RES_CONNECT_FAILED;
error[0] = new NetworkAdminException("Connect failed", e);
sem.release();
}
if (!sem.reserve(10000)) {
result[0] = RES_CONNECT_FAILED;
error[0] = new NetworkAdminException("Connect timeout");
}
if (result[0] == RES_OK) {
return (details[0]);
}
throw (error[0]);
}
use of com.biglybt.core.util.AESemaphore in project BiglyBT by BiglySoftware.
the class NetworkAdminSocksProxyImpl method testVersion.
protected void testVersion(final String version) throws NetworkAdminException {
final int RES_CONNECT_FAILED = 0;
final int RES_SOCKS_FAILED = 1;
final int RES_OK = 3;
final AESemaphore sem = new AESemaphore("NetworkAdminSocksProxy:test");
final int[] result = { RES_CONNECT_FAILED };
final NetworkAdminException[] error = { null };
try {
InetSocketAddress socks_address = new InetSocketAddress(InetAddress.getByName(host), Integer.parseInt(port));
final InetSocketAddress target_address = new InetSocketAddress(TARGET_HOST, TARGET_PORT);
TCPConnectionManager.ConnectListener connect_listener = new TCPConnectionManager.ConnectListener() {
@Override
public int connectAttemptStarted(int default_connect_timeout) {
return (default_connect_timeout);
}
@Override
public void connectSuccess(SocketChannel channel) {
final TCPTransportImpl transport = new TCPTransportImpl((ProtocolEndpointTCP) ProtocolEndpointFactory.createEndpoint(ProtocolEndpoint.PROTOCOL_TCP, target_address), false, false, null);
transport.setFilter(TCPTransportHelperFilterFactory.createTransparentFilter(channel));
new ProxyLoginHandler(transport, target_address, new ProxyLoginHandler.ProxyListener() {
@Override
public void connectSuccess() {
transport.close("Done");
result[0] = RES_OK;
sem.release();
}
@Override
public void connectFailure(Throwable failure_msg) {
transport.close("Proxy login failed");
result[0] = RES_SOCKS_FAILED;
error[0] = new NetworkAdminException("Proxy connect failed", failure_msg);
sem.release();
}
}, version, user, password);
}
@Override
public void connectFailure(Throwable failure_msg) {
result[0] = RES_CONNECT_FAILED;
error[0] = new NetworkAdminException("Connect failed", failure_msg);
sem.release();
}
};
TCPNetworkManager.getSingleton().getConnectDisconnectManager().requestNewConnection(socks_address, connect_listener, ProtocolEndpoint.CONNECT_PRIORITY_MEDIUM);
} catch (Throwable e) {
result[0] = RES_CONNECT_FAILED;
error[0] = new NetworkAdminException("Connect failed", e);
sem.release();
}
if (!sem.reserve(10000)) {
result[0] = RES_CONNECT_FAILED;
error[0] = new NetworkAdminException("Connect timeout");
}
if (result[0] != RES_OK) {
throw (error[0]);
}
}
use of com.biglybt.core.util.AESemaphore in project BiglyBT by BiglySoftware.
the class TRNonBlockingServerProcessor method runSupport.
@Override
public void runSupport() {
boolean async = false;
try {
String url = request_header.substring(request_header.indexOf(' ')).trim();
int pos = url.indexOf(" ");
url = url.substring(0, pos);
final AESemaphore[] went_async = { null };
final ByteArrayOutputStream[] async_stream = { null };
AsyncController async_control = new AsyncController() {
@Override
public void setAsyncStart() {
went_async[0] = new AESemaphore("async");
}
@Override
public void setAsyncComplete() {
went_async[0].reserve();
asyncProcessComplete(async_stream[0]);
}
};
try {
InetSocketAddress remote_sa = (InetSocketAddress) socket_channel.socket().getRemoteSocketAddress();
AEProxyAddressMapper.AppliedPortMapping applied_mapping = proxy_address_mapper.applyPortMapping(remote_sa.getAddress(), remote_sa.getPort());
remote_sa = applied_mapping.getAddress();
ByteArrayOutputStream response = process(request_header, lc_request_header, url, remote_sa, getServer().getRestrictNonBlocking(), new ByteArrayInputStream(new byte[0]), async_control);
if (response == null) {
async = true;
} else if (went_async[0] != null) {
async_stream[0] = response;
async = true;
} else {
write_buffer = ByteBuffer.wrap(response.toByteArray());
}
} finally {
if (went_async[0] != null) {
went_async[0].release();
}
}
} catch (Throwable e) {
} finally {
if (!async) {
((TRNonBlockingServer) getServer()).readyToWrite(this);
}
}
}
use of com.biglybt.core.util.AESemaphore in project BiglyBT by BiglySoftware.
the class RDResumeHandler method checkAllPieces.
public void checkAllPieces(boolean newfiles) {
// long start = System.currentTimeMillis();
DiskManagerRecheckInstance recheck_inst = disk_manager.getRecheckScheduler().register(disk_manager, false);
int overall_piece_size = disk_manager.getPieceLength();
final AESemaphore run_sem = new AESemaphore("RDResumeHandler::checkAllPieces:runsem", overall_piece_size > 32 * 1024 * 1024 ? 1 : 2);
final List<DiskManagerCheckRequest> failed_pieces = new ArrayList<>();
try {
boolean resume_data_complete = false;
try {
check_in_progress = true;
boolean resumeEnabled = use_fast_resume;
if (newfiles) {
resumeEnabled = false;
}
final AESemaphore pending_checks_sem = new AESemaphore("RD:PendingChecks");
int pending_check_num = 0;
DiskManagerPiece[] pieces = disk_manager.getPieces();
// calculate the current file sizes up front for performance reasons
DiskManagerFileInfo[] files = disk_manager.getFiles();
Map file_sizes = new HashMap();
for (int i = 0; i < files.length; i++) {
try {
Long len = new Long(((DiskManagerFileInfoImpl) files[i]).getCacheFile().getLength());
file_sizes.put(files[i], len);
} catch (CacheFileManagerException e) {
Debug.printStackTrace(e);
}
}
if (resumeEnabled) {
boolean resumeValid = false;
byte[] resume_pieces = null;
Map partialPieces = null;
Map resume_data = getResumeData();
if (resume_data != null) {
try {
resume_pieces = (byte[]) resume_data.get("resume data");
if (resume_pieces != null) {
if (resume_pieces.length != pieces.length) {
Debug.out("Resume data array length mismatch: " + resume_pieces.length + "/" + pieces.length);
resume_pieces = null;
}
}
partialPieces = (Map) resume_data.get("blocks");
resumeValid = ((Long) resume_data.get("valid")).intValue() == 1;
if (isTorrentResumeDataComplete(disk_manager.getDownloadManager().getDownloadState(), resume_data)) {
resume_data_complete = true;
} else {
// set it so that if we crash the NOT_DONE pieces will be
// rechecked
resume_data.put("valid", new Long(0));
saveResumeData(resume_data);
}
} catch (Exception ignore) {
// ignore.printStackTrace();
}
}
if (resume_pieces == null) {
check_is_full_check = true;
resumeValid = false;
resume_pieces = new byte[pieces.length];
Arrays.fill(resume_pieces, PIECE_RECHECK_REQUIRED);
}
check_resume_was_valid = resumeValid;
boolean recheck_all = use_fast_resume_recheck_all;
if (!recheck_all) {
// override if not much left undone
long total_not_done = 0;
int piece_size = disk_manager.getPieceLength();
for (int i = 0; i < pieces.length; i++) {
if (resume_pieces[i] != PIECE_DONE) {
total_not_done += piece_size;
}
}
if (total_not_done < 64 * 1024 * 1024) {
recheck_all = true;
}
}
if (Logger.isEnabled()) {
int total_not_done = 0;
int total_done = 0;
int total_started = 0;
int total_recheck = 0;
for (int i = 0; i < pieces.length; i++) {
byte piece_state = resume_pieces[i];
if (piece_state == PIECE_NOT_DONE) {
total_not_done++;
} else if (piece_state == PIECE_DONE) {
total_done++;
} else if (piece_state == PIECE_STARTED) {
total_started++;
} else {
total_recheck++;
}
}
String str = "valid=" + resumeValid + ",not done=" + total_not_done + ",done=" + total_done + ",started=" + total_started + ",recheck=" + total_recheck + ",rc all=" + recheck_all + ",full=" + check_is_full_check;
Logger.log(new LogEvent(disk_manager, LOGID, str));
}
for (int i = 0; i < pieces.length; i++) {
check_position = i;
DiskManagerPiece dm_piece = pieces[i];
disk_manager.setPercentDone(((i + 1) * 1000) / disk_manager.getNbPieces());
boolean pieceCannotExist = false;
byte piece_state = resume_pieces[i];
if (piece_state == PIECE_DONE || !resumeValid || recheck_all) {
// at least check that file sizes are OK for this piece to be valid
DMPieceList list = disk_manager.getPieceList(i);
for (int j = 0; j < list.size(); j++) {
DMPieceMapEntry entry = list.get(j);
Long file_size = (Long) file_sizes.get(entry.getFile());
if (file_size == null) {
piece_state = PIECE_NOT_DONE;
pieceCannotExist = true;
if (Logger.isEnabled())
Logger.log(new LogEvent(disk_manager, LOGID, LogEvent.LT_WARNING, "Piece #" + i + ": file is missing, " + "fails re-check."));
break;
}
long expected_size = entry.getOffset() + entry.getLength();
if (file_size.longValue() < expected_size) {
piece_state = PIECE_NOT_DONE;
pieceCannotExist = true;
if (Logger.isEnabled())
Logger.log(new LogEvent(disk_manager, LOGID, LogEvent.LT_WARNING, "Piece #" + i + ": file is too small, fails re-check. File size = " + file_size + ", piece needs " + expected_size));
break;
}
}
}
if (piece_state == PIECE_DONE) {
dm_piece.setDone(true);
} else if (piece_state == PIECE_NOT_DONE && !recheck_all) {
// if the piece isn't done and we haven't been asked to recheck all pieces
// on restart (only started pieces) then just set as not done
} else {
// if the resume data is invalid or explicit recheck needed
if (pieceCannotExist) {
dm_piece.setDone(false);
} else if (piece_state == PIECE_RECHECK_REQUIRED || !resumeValid) {
run_sem.reserve();
while (!stopped) {
if (recheck_inst.getPermission()) {
break;
}
}
if (stopped) {
break;
} else {
try {
DiskManagerCheckRequest request = disk_manager.createCheckRequest(i, null);
request.setLowPriority(true);
checker.enqueueCheckRequest(request, new DiskManagerCheckRequestListener() {
@Override
public void checkCompleted(DiskManagerCheckRequest request, boolean passed) {
if (TEST_RECHECK_FAILURE_HANDLING && (int) (Math.random() * 10) == 0) {
disk_manager.getPiece(request.getPieceNumber()).setDone(false);
passed = false;
}
if (!passed) {
synchronized (failed_pieces) {
failed_pieces.add(request);
}
}
complete();
}
@Override
public void checkCancelled(DiskManagerCheckRequest request) {
complete();
}
@Override
public void checkFailed(DiskManagerCheckRequest request, Throwable cause) {
complete();
}
protected void complete() {
run_sem.release();
pending_checks_sem.release();
}
});
pending_check_num++;
} catch (Throwable e) {
Debug.printStackTrace(e);
}
}
}
}
}
while (pending_check_num > 0) {
pending_checks_sem.reserve();
pending_check_num--;
}
if (partialPieces != null) {
Iterator iter = partialPieces.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry key = (Map.Entry) iter.next();
int pieceNumber = Integer.parseInt((String) key.getKey());
DiskManagerPiece dm_piece = pieces[pieceNumber];
if (!dm_piece.isDone()) {
List blocks = (List) partialPieces.get(key.getKey());
Iterator iterBlock = blocks.iterator();
while (iterBlock.hasNext()) {
dm_piece.setWritten(((Long) iterBlock.next()).intValue());
}
}
}
}
} else {
for (int i = 0; i < pieces.length; i++) {
check_position = i;
disk_manager.setPercentDone(((i + 1) * 1000) / disk_manager.getNbPieces());
boolean pieceCannotExist = false;
// check if there is an underlying file for this piece, if not set it to not done
DMPieceList list = disk_manager.getPieceList(i);
for (int j = 0; j < list.size(); j++) {
DMPieceMapEntry entry = list.get(j);
Long file_size = (Long) file_sizes.get(entry.getFile());
if (file_size == null) {
pieceCannotExist = true;
break;
}
long expected_size = entry.getOffset() + entry.getLength();
if (file_size.longValue() < expected_size) {
pieceCannotExist = true;
break;
}
}
if (pieceCannotExist) {
disk_manager.getPiece(i).setDone(false);
continue;
}
run_sem.reserve();
while (!stopped) {
if (recheck_inst.getPermission()) {
break;
}
}
if (stopped) {
break;
}
try {
DiskManagerCheckRequest request = disk_manager.createCheckRequest(i, null);
request.setLowPriority(true);
checker.enqueueCheckRequest(request, new DiskManagerCheckRequestListener() {
@Override
public void checkCompleted(DiskManagerCheckRequest request, boolean passed) {
if (TEST_RECHECK_FAILURE_HANDLING && (int) (Math.random() * 10) == 0) {
disk_manager.getPiece(request.getPieceNumber()).setDone(false);
passed = false;
}
if (!passed) {
synchronized (failed_pieces) {
failed_pieces.add(request);
}
}
complete();
}
@Override
public void checkCancelled(DiskManagerCheckRequest request) {
complete();
}
@Override
public void checkFailed(DiskManagerCheckRequest request, Throwable cause) {
complete();
}
protected void complete() {
run_sem.release();
pending_checks_sem.release();
}
});
pending_check_num++;
} catch (Throwable e) {
Debug.printStackTrace(e);
}
}
while (pending_check_num > 0) {
pending_checks_sem.reserve();
pending_check_num--;
}
}
if (failed_pieces.size() > 0 && !TEST_RECHECK_FAILURE_HANDLING) {
byte[][] piece_hashes = disk_manager.getTorrent().getPieces();
ByteArrayHashMap<Integer> hash_map = new ByteArrayHashMap<>();
for (int i = 0; i < piece_hashes.length; i++) {
hash_map.put(piece_hashes[i], i);
}
for (DiskManagerCheckRequest request : failed_pieces) {
while (!stopped) {
if (recheck_inst.getPermission()) {
break;
}
}
if (stopped) {
break;
}
byte[] hash = request.getHash();
if (hash != null) {
final Integer target_index = hash_map.get(hash);
int current_index = request.getPieceNumber();
int piece_size = disk_manager.getPieceLength(current_index);
if (target_index != null && target_index != current_index && disk_manager.getPieceLength(target_index) == piece_size && !disk_manager.isDone(target_index)) {
final AESemaphore sem = new AESemaphore("PieceReorder");
disk_manager.enqueueReadRequest(disk_manager.createReadRequest(current_index, 0, piece_size), new DiskManagerReadRequestListener() {
@Override
public void readCompleted(DiskManagerReadRequest request, DirectByteBuffer data) {
try {
disk_manager.enqueueWriteRequest(disk_manager.createWriteRequest(target_index, 0, data, null), new DiskManagerWriteRequestListener() {
@Override
public void writeCompleted(DiskManagerWriteRequest request) {
try {
DiskManagerCheckRequest check_request = disk_manager.createCheckRequest(target_index, null);
check_request.setLowPriority(true);
checker.enqueueCheckRequest(check_request, new DiskManagerCheckRequestListener() {
@Override
public void checkCompleted(DiskManagerCheckRequest request, boolean passed) {
sem.release();
}
@Override
public void checkCancelled(DiskManagerCheckRequest request) {
sem.release();
}
@Override
public void checkFailed(DiskManagerCheckRequest request, Throwable cause) {
sem.release();
}
});
} catch (Throwable e) {
sem.release();
}
}
@Override
public void writeFailed(DiskManagerWriteRequest request, Throwable cause) {
sem.release();
}
});
} catch (Throwable e) {
sem.release();
}
}
@Override
public void readFailed(DiskManagerReadRequest request, Throwable cause) {
sem.release();
}
@Override
public int getPriority() {
return (-1);
}
@Override
public void requestExecuted(long bytes) {
}
});
sem.reserve();
}
}
}
}
} finally {
check_in_progress = false;
}
if (!(stopped || resume_data_complete)) {
try {
saveResumeData(true);
} catch (Exception e) {
Debug.out("Failed to dump initial resume data to disk");
Debug.printStackTrace(e);
}
}
} catch (Throwable e) {
// if something went wrong then log and continue.
Debug.printStackTrace(e);
} finally {
recheck_inst.unregister();
// System.out.println( "Check of '" + disk_manager.getDownloadManager().getDisplayName() + "' completed in " + (System.currentTimeMillis() - start));
}
}
use of com.biglybt.core.util.AESemaphore in project BiglyBT by BiglySoftware.
the class PluginEngine method searchSupport.
@Override
protected Result[] searchSupport(SearchParameter[] params, Map searchContext, final int desired_max_matches, final int absolute_max_matches, String headers, final ResultListener listener) throws SearchException {
if (provider == null) {
provider = getMetaSearch().resolveProvider(this);
if (provider == null) {
return (new Result[0]);
}
}
Map search_parameters = new HashMap();
String term = null;
for (int i = 0; i < params.length; i++) {
SearchParameter param = params[i];
String pattern = param.getMatchPattern();
String value = param.getValue();
if (pattern.equals("s")) {
term = value;
search_parameters.put(SearchProvider.SP_SEARCH_TERM, value);
} else if (pattern.equals("m")) {
search_parameters.put(SearchProvider.SP_MATURE, Boolean.valueOf(value));
} else if (pattern.equals("n")) {
String[] networks = value.split(",");
search_parameters.put(SearchProvider.SP_NETWORKS, networks);
} else {
Debug.out("Unrecognised search parameter '" + pattern + "=" + value + "' ignored");
}
}
final String f_term = term;
try {
final List<PluginResult> results = new ArrayList<>();
final AESemaphore sem = new AESemaphore("waiter");
provider.search(search_parameters, new SearchObserver() {
private boolean complete = false;
@Override
public void resultReceived(SearchInstance search, SearchResult result) {
PluginResult p_result = new PluginResult(PluginEngine.this, result, f_term);
synchronized (this) {
if (complete) {
return;
}
results.add(p_result);
}
if (listener != null) {
listener.resultsReceived(PluginEngine.this, new Result[] { p_result });
}
synchronized (this) {
if (absolute_max_matches >= 0 && results.size() >= absolute_max_matches) {
complete = true;
sem.release();
}
}
}
@Override
public void cancelled() {
sem.release();
}
@Override
public void complete() {
sem.release();
}
@Override
public Object getProperty(int property) {
if (property == PR_MAX_RESULTS_WANTED) {
return (new Long(desired_max_matches));
}
return (null);
}
});
sem.reserve();
if (listener != null) {
listener.resultsComplete(this);
}
return ((Result[]) results.toArray(new Result[results.size()]));
} catch (Throwable e) {
throw (new SearchException("Search failed", e));
}
}
Aggregations