انتقال فایل

THIS PAGE IS DEPRECATED: READ File transfer

چطوري ازش استفاده کنم؟

Android

وقتی با کسی در اندروید صحبت می کنید، شما امکان ارسال یک عکس در دستگاه خود یا گرفتن یک عکس با این دکمه ها را دارید:

Android_file_buttons

توجه

When you send a file, the other has to accept it. At this moment you will see 'awaiting peer':

Android_awaiting_peer

چطور کار ميکنه؟

چطور کار می کنه

مقدمه

Jami یک برنامه توزیع شده است و باید بدون هیچ اتصال به اینترنت کار کند. پس انتقال فایل نیز! اساساً، ما برای انجام انتقال فایل و تماس ها از همان روش استفاده می کنیم، اما در TCP. برای خلاصه کردن نحوه کار آن، می توانیم یک موقعیت را تصور کنیم که آلیس (A) می خواهد یک فایل را به باب (B) انتقال دهد.

First, Alice will request a connection to Bob. To do that, Jami is using ICE (RFC 6544), a protocol used to negotiate links between peers. Alice will send, into an encrypted packet via the DHT the IP address of its device. So, when Bob receives the IP addresses of Alice, they will be able to negotiate a transport where Bob will be able to send packets to Alice. The negotiation can be successful, but if it fails, a TURN server will be used (the one configured into the settings) to perform the transfer. If the negotiation succeeds, Bob will send its IP addresses to Alice to perform the negotiation in the other direction. Note that the link is still not secure, so Bob will send the IP addresses through the DHT network in an encrypted message. If the second negotiation fails, the TURN will be used as a fallback.

حالا که لینک دو جهت TCP اینجاست، مرحله بعدی مذاکره یک TLS 1.3 (به طور کلی یک (TLS1.3)-(DHE-FFDHE8192)-(RSA-PSS-RSAE-SHA384)-(AES-256-GCM) است که من این خطوط را می نویسم) بین آلیس و باب، سپس آلیس شروع به انتقال فایل می کند.

بخش اول یک سر و کله کوچک برای توصیف محتوای فایل خواهد بود. سپس، پس از اینکه باب انتقال را قبول می کند، فایل کامل ارسال خواهد شد.

فرآیند

ارسال پرونده

روش زیر استفاده می شود:

  1. A client will call DataTransferFacade::sendFile(). DataTransferFacade is the class corresponding to the API exposed for the clients. It is used to manage a view of the file transfers (the corresponding classes are DataTransfer, IncomingFileTransfer, OutgoingFileTransfer and SubOutgoingFileTransfer). This method will ask the linked JamiAccount to request a connection. Diagram: DataTransfer class diagram

  2. The method DhtPeerConnector: requestConnection() is triggered and creates a connection between all connected devices of the peer (found on the DHT). DhtPeerConnector is used to manage the main event loop which manage connections. When a device is found, the event loop will create a ClientConnector (which manage the connection for one device) and launch the process() method.

  3. This method is used to initialize the ICE transport and put a PeerConnectionMsg (which contains the SDP message, see below) on the DHT and waits for a response (DhtPeerConnector::Impl::onResponseMsg).

  4. Then a response is received from the DHT, which contains public addresses of the peer device. We can now negotiate a TLS link (directly via ICE, or via TURN as a fallback). This TlsSocketEndpoint is given to the PeerConnection object as an output and the transfer can start.

  5. When the TLS socket is ready, the callback DataTransferFacade::Impl::onConnectionRequestReply is called, and a OutgoingFileTransfer is linked to the PeerConnection as an input. This OutgoingFileTransfer contains a list of SubOutgoingFileTransfer (one per device) where each sub transfer is a transfer to one device. We do that to be able to furnish the most optimistic view of the transfer (if a contact as 3 devices, where the contact cancel the transfer on one device, but accepted the transfer on the two others, the most advanced transfer will be shown).

  6. The SubOutgoingFileTransfer will first transfer the header of the file, wait the peer acceptance (A "GO\n" message on the socket) and then will send the file.

  7. If a cancel is received from the peer or the client or if the file transfer finish, the connection will be closed via a CANCEL message on the DhtPeerConnector::eventLoop() and the resources will be released.

! TLSsocketEndpoint

دریافت فایل

از همان ساختار برای دریافت فایل ها استفاده می شود، اما روش کمی تغییر می کند:

  1. کلاس JamiAccount برای دریافت پیام های DHT استفاده می شود، زیرا اولین چیزی که دریافت می شود درخواست DHT خواهد بود.

  2. سپس این پیام به DhtPeerConnector: onRequestMessage() از طریق eventLoop داده می شود.

  3. DhtPeerConnector::Impl::answerToRequest سعی خواهد کرد به سرور TURN متصل شود (اگر متصل نشده باشد) و حمل و نقل ICE را آغاز کند. این روش دو اتصال کنترل را به یک سرور TURN باز می کند (یک برای مجوز IPV4 همتایان، دیگری برای همتایان IPv6 ، به دلیل RFC 6156) اگر هنوز باز نشده باشد و اجازه اتصال آدرس های عمومی همتایان را می دهد. سپس ، اگر SDP دریافت شده شامل کاندیداهای ICE نیست ، از TURN استفاده می کند و پاسخ SDP را برای انتظار همتایان ایجاد می کند. اگر SDP شامل کاندیداهای ICE باشد ، روش سعی خواهد کرد که در مورد لینک مذاکره (یا بازگشت به TURN) و سپس به SDP پاسخ دهد (با کاندیداهای ICE یا نه).

  4. هنگامی که لینک ها آماده هستند، مانند فرستنده، یک لینک TLS مذاکره می شود و به PeerConnection داده می شود تا به IncomingFileTransfer به عنوان ورودی داده شود. سرنخ های فایل می آیند و مشتری اکنون می تواند انتقال را بپذیرد یا لغو کند.

دوباره درخواست انتقال فایل قبلی

As specified in Other mime types, the data-transfer interactions are now synced and stored into conversations. So, a device can easily detects if a file was downloaded or not. If not, it can asks all members in the conversation to transmits the file again.

برای انجام این کار، دستگاه یک json با نوع mime ارسال می کند: application/data-transfer-request+json حاوی conversation (ID مکالمه) ، interaction (تفاعل مرتبط) ، deviceId دستگاه دریافت کننده فایل.

فرستنده اکنون بررسی می کند که آیا دستگاه یک دستگاه از همتایان اعلام شده است و آیا دستگاه عضو مکالمه است و می تواند فایل را از طریق انتقال فایل کلاسیک ارسال کند.

گیرنده می تواند اولین انتقال وارد شده را قبول کند، فایل را دانلود کند و تأیید کند که sha3sum درست است.

طرح

![ نمودار: نمودار طرح اصلی](تصاویر/فايل-تحويل-نماینه اصلی- نمودار.png)

SDP از طریق DHT ارسال شد
0d04b932
7c33834e7cf944bf0e367b47
H6e6ca682 1 TCP 2130706431 2607:fad8:4:6:9eb6:d0ff:dead:c0de 50693 typ host tcptype passive
H6e6ca682 1 TCP 2130706431 2607:fad8:4:6:9eb6:d0ff:dead:c0de 9 typ host tcptype active
H42c1b577 1 TCP 2130706431 fe80::9eb6:d0ff:fee7:1412 50693 typ host tcptype passive
H42c1b577 1 TCP 2130706431 fe80::9eb6:d0ff:fee7:1412 9 typ host tcptype active
Hc0a8007e 1 TCP 2130706431 192.168.0.123 42751 typ host tcptype passive
Hc0a8007e 1 TCP 2130706431 192.168.0.123 9 typ host tcptype active
Sc0a8007e 1 TCP 1694498815 X.X.X.X 42751 typ srflx tcptype passive
Z.Z.Z.Z:YYYY
A.A.A.A:YYYY

Where 0d04b932 is the ufrag and 7c33834e7cf944bf0e367b47 the password of the ICE session. 2130706431 and 1694498815 are the priority of the candidates. 192.168.0.126 42751 typ host tcptype passive is a passive host candidate and 1694498815 X.X.X.X 42751 typ srflx tcptype passive a passive host reflecting the public IP address (mapped via UPnP for example).

دستگاه های متعدد

A user can link its account to several devices. So, we need to implement the transfer when a user send a file to a contact who have multiple devices linked to this account.

اولین رویکرد

اولین رویکرد این بود که درخواست را از طریق DHT به تمام دستگاه ها ارسال کنید و اولین دستگاه هایی که پاسخ می دهند فایل را انتقال دهند. این برای تماس شما بد است زیرا آنها نمی دانند که کدام دستگاه دریافت خواهد کرد انتقال را دریافت می کند.

رویکرد فعلی

حالا ما هنوز یک درخواست را به تمام دستگاه ها می فرستیم. تفاوت این است که همه دستگاه ها اطلاعیه برای دریافت یک فایل دارند و می توانند انتقال را بپذیرند / رد کنند. بخش عمده ای از کد برای آن در *data_transfer.cpp است.

Now (since https://review.jami.net/c/jami-daemon/+/9327), when a user send a file, it will request a PeerConnection with all peer devices. And for all connections, we attach a new input stream to have the ability to accept/refuse/cancel each transfer separately.

در data_transfer.cpp ما کلاس OptimisticMetaOutgoingInfo را تعریف می کنیم که نمایش دیدگاه خوش بینانه را برای نمایش به مشتری نشان می دهد. این خوش بینانه است زیرا اگر یک تماس انتقال را در یک دستگاه پذیرفته و در دستگاه های دیگر رد کند، این کلاس انتقال فایل در حال انجام را نشان می دهد. و فقط در صورتی خطا را نشان می دهد که تمام دستگاه ها انتقال را رد کنند.

این کلاس به SubOutgoingFileTransfer مرتبط است که وضعیت انتقال را با یک دستگاه نشان می دهد. مشتریان قادر خواهند بود یک انتقال زیر را به جای خوشبینانه بعد نشان دهند (به لیست TODO مراجعه کنید).

با استفاده از سرور دیگر TURN

Actually the default TURN server is turn.jami.net. But you can host your own TURN server. For example by running a coTURN server.

`sudo turnserver -a -v -n -u user:password -r "realm"

Then, you can configure the TURN server in the advanced settings of the app.

توجه

This needs some technical knowledge. Moreover, the TURN server should see the same IP address of your node as the destination node, or the peer connection will fail (because the authorization will be incorrect).

فهرست تمام

  1. Use libtorrent?

  2. وضعیت انتقال زیر برای فایل های خارج شده را نمایش دهید