SlideShare ist ein Scribd-Unternehmen logo
1 von 37
Scalable application layer transfers
Daniel Stenberg
●
Free Software
●
Network hacker, code and IETF
●
Embedded developer
●
Consultant
Email: daniel@haxx.se
Twitter: @bagder
Web: daniel.haxx.se
Blog: daniel.haxx.se/blog
Agenda
●
Traditional network client
●
… applied to libcurl
●
C10K
●
… applied to libcurl
Protocol stack
Contents
Application
Transport
Internet
Link
libcurl
●
curl.haxx.se
●
Very portable C library
●
Application protocol transfers: DICT, FILE, FTP, FTPS, 
GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, 
POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and 
TFTP
●
Roots from 1997
●
MIT licensed
●
Daniel is lead developer
A typical client
●
Create socket
●
Connect socket
●
Select() for data to read or write
●
Read or write data
●
Loop
pseudo C code
WARNING
the following source code 
examples are not complete and 
they resemble C code
int main(int argc, char *argv[])
{
int sock; /* Socket descriptor */
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithError("socket() failed");
/* it would resolve the host name here */
if (connect(sock to server))
DieWithError("connect() failed");
do {
select(maxfd+1, sock, …); /* wait for socket to become readable
or writable */
if(check sock if writable)
send(sock, string, string_len, 0);
if(check sock if readable)
recv(sock, string, string_len, 0);
} while(everything is fine);
close(sock);
exit(0);
}
School book example
1
2
1
3
4
5
Simple case works fine
●
Easy to read
●
Fast to write
●
Easy to learn and teach
int main(int argc, char *argv[])
{
int sock[NUM_CONNS]; /* Socket descriptors */
for(i=0; i< NUM_CONNS; i++) {
if ((sock[i] = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithError("socket() failed");
if (connect(sock[i] to server[i]))
DieWithError("connect() failed");
do {
/* set up the bitmasks for select() */
select(maxfd+1, sock, …); /* wait for any socket to become readable
or writable */
for(i=0; i< NUM_CONNS; i++) {
if(check sock[i] if writable)
send(sock, string, string_len, 0);
if(check sock[i] if readable)
recv(sock, string, string_len);
}
} while(everything is fine);
close(sock);
exit(0);
}
More connections
1
2
1
3
4
5
int main(int argc, char *argv[])
{
int sock[NUM_CONNS]; /* Socket descriptors */
for(i=0; i< NUM_CONNS; i++) {
if ((sock[i] = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithError("socket() failed");
if (connect(sock[i] to server[i]))
DieWithError("connect() failed");
do {
/* set up the bitmasks for select() */
select(maxfd+1, sock, …); /* wait for any socket to become readable
or writable */
for(i=0; i< NUM_CONNS; i++) {
if(check sock[i] if writable)
send(sock, string, string_len, 0);
if(check sock[i] if readable)
recv(sock, string, string_len);
}
} while(everything is fine);
close(sock);
exit(0);
}
More connections
Many connections
●
Quickly degrades
●
select() and poll() suck
●
select() slightly more due to 
FD_SETSIZE
●
Threads help to some degree, 
but...
what about libcurl
●
examples in C
●
has bindings for 40 languages
libcurl simple app
int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}
easy interface
●
easy to write
●
synchronous
●
supports many protocols in one 
go
●
made for single transfers
libcurl multi app
int main(int argc, char **argv)
{
handle1 = curl_easy_init();
handle2 = curl_easy_init();
curl_easy_setopt(handle1, CURLOPT_URL, "http://www.example.com/");
curl_easy_setopt(handle2, CURLOPT_URL, "http://fscons.org/");
multi_handle = curl_multi_init();
curl_multi_add_handle(multi_handle, handle1);
curl_multi_add_handle(multi_handle, handle2);
curl_multi_perform(multi_handle, &still_running);
while(still_running) {
curl_multi_timeout(multi_handle, &curl_timeo);
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
if(rc says timeout or readable/writable sockets)
curl_multi_perform(multi_handle, &still_running);
}
curl_multi_cleanup(multi_handle);
curl_easy_cleanup(http_handle);
curl_easy_cleanup(http_handle2);
return 0;
}
1
2
5
4
6
3
7
8
libcurl multi app
int main(int argc, char **argv)
{
handle1 = curl_easy_init();
handle2 = curl_easy_init();
curl_easy_setopt(handle1, CURLOPT_URL, "http://www.example.com/");
curl_easy_setopt(handle2, CURLOPT_URL, "http://fscons.org/");
multi_handle = curl_multi_init();
curl_multi_add_handle(multi_handle, handle1);
curl_multi_add_handle(multi_handle, handle2);
curl_multi_perform(multi_handle, &still_running);
while(still_running) {
curl_multi_timeout(multi_handle, &curl_timeo);
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
if(rc says timeout or readable/writable sockets)
curl_multi_perform(multi_handle, &still_running);
}
curl_multi_cleanup(multi_handle);
curl_easy_cleanup(http_handle);
curl_easy_cleanup(http_handle2);
return 0;
}
multi interface
●
several “easy” handles dealt with 
combined
●
made for simultaneous transfers
●
still easy to write and read
●
but: relies on select()
select with many
Scale to c10K
●
10000 simultaneous connections
●
not as easy as it may sound
A better way
●
event­based
●
react only on the sockets that 
have changed actions
●
no “check for action”
●
no loops
really scalable
not that portable
●
There's no POSIX for event­based
●
The portable libs don't support all 
platforms
●
epoll (Linux), kqueue (FreeBSD, NetBSD, 
OpenBSD, Darwin), /dev/poll (Solaris, HPUX), 
pollset (AIX), Event Completion (Solaris 10), I/O 
Completion Ports (Microsoft Windows)
libev and libevent
●
potent event libraries we base the 
examples on in this presentation
●
they support a subset of platforms
●
the examples are not complete now 
either
event­based basics
●
detail what sockets we work with 
and what do we wait for on the 
sockets
●
timeouts
●
wait until something happens
simple event client
int function(int socketfd)
{
ev = ev_default_loop();
ev_timer_init(..., timer_callback, …);
ev_io_init(ev, event_callback, socketfd, WHAT);
ev_loop(ev); /* sit here until done */
}
int timer_callback(...)
{
/* timer expired! */
}
int event_callback(..., int socketfd, ...)
{
/* something happened on my socket, now we
recv or send etc */
}
event based compared
●
different code­flow
●
might require a different state 
machine for the protocol
●
again: not widely portable
Other ways to avoid 
wrongs
●
one thread per connection with 
blocking sockets
●
threads with non­blocking i/o to 
handle N connections each
using libcurl scalable
●
“multi_socket” API added 2006
●
tells the app what sockets to wait for 
what on
●
app then speaks with event library
●
avoids select()
●
event system agnostic
libcurl multi_socket 
bindings
●
not always supported
●
a matter of writing the glue code 
correct – you can help!
multi_socket example
int main()
{
CURLM *multi = curl_multi_init();
CURL *easy;
curl_multi_setopt(..., CURLMOPT_SOCKETFUNCTION, socket_cb);
curl_multi_setopt(..., CURLMOPT_TIMERFUNCTION, timer_cb);
easy = curl_easy_init();
curl_easy_setopt(..., CURLOPT_URL, …);
curl_multi_add_handle(..., easy);
event_dispatch(); /* start the libevent dispatch
loop */
}
int event_cb(...)
{
/* event library found event on libcurl's socket, act */
curl_multi_socket_action(..., action, ...);
}
int socket_cb(...)
{
/* called when libcurl adds, removes or changes a socket that
we must deal with */
event_set(..., event_cb); /* tell event lib about setup */
}
Scales?
●
done 70,000+ connections
●
port numbers are 16 bit
●
callbacks take time thus limit 
throughput
Which protocols?
●
(almost) all network based ones 
libcurl support! (DICT, FTP, FTPS, GOPHER, 
HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, 
POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS and 
TFTP)
Caveats?
●
yeah sure, but...
●
c­ares for name resolving
●
not everything is non­blocking
More factors
●
Network stack inefficiency
●
Stack size?
●
Memory / mallocs
●
“Other” code may slow down things
●
Copy copy copy copy ...
For you who fell asleep
●
old style socket applications 
don't scale
●
use event based concepts
●
libcurl can too
libcurl is...
●
entirely open source
●
in need of your help!
●
at http://curl.haxx.se/libcurl/

Weitere ähnliche Inhalte

Was ist angesagt?

Lcu14 101- coresight overview
Lcu14 101- coresight overviewLcu14 101- coresight overview
Lcu14 101- coresight overview
Linaro
 

Was ist angesagt? (20)

Clang: More than just a C/C++ Compiler
Clang: More than just a C/C++ CompilerClang: More than just a C/C++ Compiler
Clang: More than just a C/C++ Compiler
 
Bsdtw17: johannes m dieterich: high performance computing and gpu acceleratio...
Bsdtw17: johannes m dieterich: high performance computing and gpu acceleratio...Bsdtw17: johannes m dieterich: high performance computing and gpu acceleratio...
Bsdtw17: johannes m dieterich: high performance computing and gpu acceleratio...
 
Golang
GolangGolang
Golang
 
Programming languages
Programming languagesProgramming languages
Programming languages
 
Specialized Compiler for Hash Cracking
Specialized Compiler for Hash CrackingSpecialized Compiler for Hash Cracking
Specialized Compiler for Hash Cracking
 
OpenZFS code repository
OpenZFS code repositoryOpenZFS code repository
OpenZFS code repository
 
Skydive, real-time network analyzer
Skydive, real-time network analyzer Skydive, real-time network analyzer
Skydive, real-time network analyzer
 
Try to implement Blockchain using libp2p
Try to implement Blockchain using libp2pTry to implement Blockchain using libp2p
Try to implement Blockchain using libp2p
 
mdc_ppt
mdc_pptmdc_ppt
mdc_ppt
 
Google Dart
Google DartGoogle Dart
Google Dart
 
Skydive 5/07/2016
Skydive 5/07/2016Skydive 5/07/2016
Skydive 5/07/2016
 
Get rid of TLS certificates - using IPSec for large scale cloud protection
Get rid of TLS certificates - using IPSec for large scale cloud protectionGet rid of TLS certificates - using IPSec for large scale cloud protection
Get rid of TLS certificates - using IPSec for large scale cloud protection
 
Redis: Lua scripts - a primer and use cases
Redis: Lua scripts - a primer and use casesRedis: Lua scripts - a primer and use cases
Redis: Lua scripts - a primer and use cases
 
Skydive, real-time network analyzer, container integration
Skydive, real-time network analyzer, container integrationSkydive, real-time network analyzer, container integration
Skydive, real-time network analyzer, container integration
 
A la découverte de TypeScript
A la découverte de TypeScriptA la découverte de TypeScript
A la découverte de TypeScript
 
Skydive 31 janv. 2016
Skydive 31 janv. 2016Skydive 31 janv. 2016
Skydive 31 janv. 2016
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoA Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to Go
 
Lcu14 101- coresight overview
Lcu14 101- coresight overviewLcu14 101- coresight overview
Lcu14 101- coresight overview
 
Fluent-bit
Fluent-bitFluent-bit
Fluent-bit
 
Tcp sockets
Tcp socketsTcp sockets
Tcp sockets
 

Ähnlich wie Fscons scalable appplication transfers

01 linux-quick-start
01 linux-quick-start01 linux-quick-start
01 linux-quick-start
Nguyen Vinh
 
Tornado Web Server Internals
Tornado Web Server InternalsTornado Web Server Internals
Tornado Web Server Internals
Praveen Gollakota
 
A Kernel of Truth: Intrusion Detection and Attestation with eBPF
A Kernel of Truth: Intrusion Detection and Attestation with eBPFA Kernel of Truth: Intrusion Detection and Attestation with eBPF
A Kernel of Truth: Intrusion Detection and Attestation with eBPF
oholiab
 
DevSecCon London 2019: A Kernel of Truth: Intrusion Detection and Attestation...
DevSecCon London 2019: A Kernel of Truth: Intrusion Detection and Attestation...DevSecCon London 2019: A Kernel of Truth: Intrusion Detection and Attestation...
DevSecCon London 2019: A Kernel of Truth: Intrusion Detection and Attestation...
DevSecCon
 

Ähnlich wie Fscons scalable appplication transfers (20)

Mender.io | Develop embedded applications faster | Comparing C and Golang
Mender.io | Develop embedded applications faster | Comparing C and GolangMender.io | Develop embedded applications faster | Comparing C and Golang
Mender.io | Develop embedded applications faster | Comparing C and Golang
 
C++primer
C++primerC++primer
C++primer
 
Rlite software-architecture (1)
Rlite software-architecture (1)Rlite software-architecture (1)
Rlite software-architecture (1)
 
10 reasons to be excited about go
10 reasons to be excited about go10 reasons to be excited about go
10 reasons to be excited about go
 
Building scalable and language independent java services using apache thrift
Building scalable and language independent java services using apache thriftBuilding scalable and language independent java services using apache thrift
Building scalable and language independent java services using apache thrift
 
01 linux-quick-start
01 linux-quick-start01 linux-quick-start
01 linux-quick-start
 
Fedora Developer's Conference 2014 Talk
Fedora Developer's Conference 2014 TalkFedora Developer's Conference 2014 Talk
Fedora Developer's Conference 2014 Talk
 
Rust and Eclipse
Rust and EclipseRust and Eclipse
Rust and Eclipse
 
Tips and Tricks for Increased Development Efficiency
Tips and Tricks for Increased Development EfficiencyTips and Tricks for Increased Development Efficiency
Tips and Tricks for Increased Development Efficiency
 
Monitoring.pptx
Monitoring.pptxMonitoring.pptx
Monitoring.pptx
 
DSD-INT 2014 - Delft3D Open Source Workshop - Qinghua Ye & Adri Mourits, Delt...
DSD-INT 2014 - Delft3D Open Source Workshop - Qinghua Ye & Adri Mourits, Delt...DSD-INT 2014 - Delft3D Open Source Workshop - Qinghua Ye & Adri Mourits, Delt...
DSD-INT 2014 - Delft3D Open Source Workshop - Qinghua Ye & Adri Mourits, Delt...
 
Dart the Better JavaScript
Dart the Better JavaScriptDart the Better JavaScript
Dart the Better JavaScript
 
Tornado Web Server Internals
Tornado Web Server InternalsTornado Web Server Internals
Tornado Web Server Internals
 
Ruxmon.2013-08.-.CodeBro!
Ruxmon.2013-08.-.CodeBro!Ruxmon.2013-08.-.CodeBro!
Ruxmon.2013-08.-.CodeBro!
 
Socket Programming with Python
Socket Programming with PythonSocket Programming with Python
Socket Programming with Python
 
A Kernel of Truth: Intrusion Detection and Attestation with eBPF
A Kernel of Truth: Intrusion Detection and Attestation with eBPFA Kernel of Truth: Intrusion Detection and Attestation with eBPF
A Kernel of Truth: Intrusion Detection and Attestation with eBPF
 
DevSecCon London 2019: A Kernel of Truth: Intrusion Detection and Attestation...
DevSecCon London 2019: A Kernel of Truth: Intrusion Detection and Attestation...DevSecCon London 2019: A Kernel of Truth: Intrusion Detection and Attestation...
DevSecCon London 2019: A Kernel of Truth: Intrusion Detection and Attestation...
 
Building scalable and language-independent Java services using Apache Thrift ...
Building scalable and language-independent Java services using Apache Thrift ...Building scalable and language-independent Java services using Apache Thrift ...
Building scalable and language-independent Java services using Apache Thrift ...
 
Challenges in GPU compilers
Challenges in GPU compilersChallenges in GPU compilers
Challenges in GPU compilers
 
Apache Thrift
Apache ThriftApache Thrift
Apache Thrift
 

Mehr von Daniel Stenberg

Mehr von Daniel Stenberg (20)

mastering libcurl part 2
mastering libcurl part 2mastering libcurl part 2
mastering libcurl part 2
 
mastering libcurl part 1
mastering libcurl part 1mastering libcurl part 1
mastering libcurl part 1
 
curl - openfourm europe.pdf
curl - openfourm europe.pdfcurl - openfourm europe.pdf
curl - openfourm europe.pdf
 
curl experiments - curl up 2022
curl experiments - curl up 2022curl experiments - curl up 2022
curl experiments - curl up 2022
 
curl security - curl up 2022
curl security - curl up 2022curl security - curl up 2022
curl security - curl up 2022
 
HTTP/3 in curl - curl up 2022
HTTP/3 in curl - curl up 2022HTTP/3 in curl - curl up 2022
HTTP/3 in curl - curl up 2022
 
The state of curl 2022
The state of curl 2022The state of curl 2022
The state of curl 2022
 
Let me tell you about curl
Let me tell you about curlLet me tell you about curl
Let me tell you about curl
 
Curl with rust
Curl with rustCurl with rust
Curl with rust
 
Getting started with libcurl
Getting started with libcurlGetting started with libcurl
Getting started with libcurl
 
HTTP/3 is next generation HTTP
HTTP/3 is next generation HTTPHTTP/3 is next generation HTTP
HTTP/3 is next generation HTTP
 
Landing code in curl
Landing code in curlLanding code in curl
Landing code in curl
 
Testing curl for security
Testing curl for securityTesting curl for security
Testing curl for security
 
common mistakes when using libcurl
common mistakes when using libcurlcommon mistakes when using libcurl
common mistakes when using libcurl
 
HTTP/3 in curl 2020
HTTP/3 in curl 2020HTTP/3 in curl 2020
HTTP/3 in curl 2020
 
The state of curl 2020
The state of curl 2020The state of curl 2020
The state of curl 2020
 
curl roadmap 2020
curl roadmap 2020curl roadmap 2020
curl roadmap 2020
 
curl better
curl bettercurl better
curl better
 
HTTP/3 for everyone
HTTP/3 for everyoneHTTP/3 for everyone
HTTP/3 for everyone
 
HTTP/3, QUIC and streaming
HTTP/3, QUIC and streamingHTTP/3, QUIC and streaming
HTTP/3, QUIC and streaming
 

Kürzlich hochgeladen

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 

Kürzlich hochgeladen (20)

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 

Fscons scalable appplication transfers